#include "edgedetector.h"

EdgeDetector::EdgeDetector()
{

}
QImage EdgeDetector::sideGradient(const QImage &image)
{
    int width = image.width();
    int height = image.height();
    QImage ret = image.copy();
    for(int y = 0; y < height - 1; y ++)
    {
        const uchar * line = image.constScanLine(y);
        const uchar * next = image.constScanLine(y + 1);
        uchar * out = ret.scanLine(y);
        for(int x = 0; x < width - 1; x ++)
        {            
            int z = abs(line[x] - line[x + 1]) + abs(line[x] - next[x]);
            out[x] = qBound(0, z, 255);
        }
    }
    return ret;
}

QImage EdgeDetector::horizontalGradient(const QImage &image)
{
    int width = image.width();
    int height = image.height();
    QImage ret = image.copy();
    for(int y = 0; y < height; y ++)
    {
        const uchar * line = image.constScanLine(y);
        uchar * out = ret.scanLine(y);
        for(int x = 0; x < width - 1; x ++)
        {            
            int z = abs(line[x] - line[x + 1]);
            out[x] = qBound(0, z, 255);
        }
    }
    return ret;	
}
QImage EdgeDetector::verticalGradient(const QImage &image)
{
    int width = image.width();
    int height = image.height();
    QImage ret = image.copy();
    for(int y = 0; y < height - 1; y ++)
    {
        const uchar * line = image.constScanLine(y);
        const uchar * next = image.constScanLine(y + 1);
        uchar * out = ret.scanLine(y);
        for(int x = 0; x < width; x ++)
        {            
            int z = abs(line[x] - next[x]);
            out[x] = qBound(0, z, 255);
        }
    }
    return ret;
}

QImage EdgeDetector::horizontalGradient2(const QImage &image)
{
    int width = image.width();
    int height = image.height();
    QImage ret = image.copy();
    for(int y = 0; y < height; y ++)
    {
        const uchar * line = image.constScanLine(y);
        uchar * out = ret.scanLine(y);
        for(int x = 1; x < width - 1; x ++)
        {            
            int z = abs(line[x - 1] - line[x + 1]);
            out[x] = qBound(0, z, 255);
        }
    }
    return ret;		
}

QImage EdgeDetector::verticalGradient2(const QImage &image)
{
    int width = image.width();
    int height = image.height();
    QImage ret = image.copy();
    for(int y = 1; y < height - 1; y ++)
    {
        const uchar * line = image.constScanLine(y - 1);
        const uchar * next = image.constScanLine(y + 1);
        uchar * out = ret.scanLine(y);
        for(int x = 0; x < width; x ++)
        {            
            int z = abs(line[x] - next[x]);
            out[x] = qBound(0, z, 255);
        }
    }
    return ret;
}

QImage EdgeDetector::RobertsDetector(const QImage &image, int type)
{
	int width = image.width();
    int height = image.height();
    QImage ret = image.copy();
	if(type == 0)
	{
		for(int y = 0; y < height - 1; y ++)
		{
			const uchar * line = image.constScanLine(y);
			const uchar * next = image.constScanLine(y + 1);
			uchar * out = ret.scanLine(y);
			for(int x = 0; x < width - 1; x ++)
			{          
				int mm = abs(line[x] - next[x + 1]);
				out[x] = qBound(0,mm, 255);
			}
		}		
	}
	else if(type == 1)
	{
		for(int y = 0; y < height - 1; y ++)
		{
			const uchar * line = image.constScanLine(y);
			const uchar * next = image.constScanLine(y + 1);
			uchar * out = ret.scanLine(y);
			for(int x = 0; x < width - 1; x ++)
			{          
				int mp = abs(line[x + 1] - next[x]);
				out[x] = qBound(0, mp, 255);
			}
		}			
	}
	else
	{
		for(int y = 0; y < height - 1; y ++)
		{
			const uchar * line = image.constScanLine(y);
			const uchar * next = image.constScanLine(y + 1);
			uchar * out = ret.scanLine(y);
			for(int x = 0; x < width - 1; x ++)
			{          
				int mm = abs(line[x] - next[x + 1]);
				int mp = abs(line[x + 1] - next[x]);
                int z = qMax(mm, mp);
				out[x] = qBound(0, z, 255);
			}
		}	
	}
    return ret;
}

QImage EdgeDetector::SobelDetector(const QImage &image, int type)
{
    int width = image.width();
    int height = image.height();
    QImage ret = image.copy();
    if(type == 0)
    {
        for(int y = 1; y < height - 1; y ++)
        {
            const uchar * last = image.constScanLine(y - 1);
            const uchar * line = image.constScanLine(y);
            const uchar * next = image.constScanLine(y + 1);
            uchar * out = ret.scanLine(y);
            for(int x = 1; x < width - 1; x ++)
            {
                int z = abs(last[x - 1] - last[x + 1]
                        + 2 * (line[x - 1] - line[x + 1])
                        + next[x - 1] - next[x + 1]);
                out[x] = qBound(0, z, 255);
            }
        }
    }
    else if(type == 1)
    {
        for(int y = 1; y < height - 1; y ++)
        {
            const uchar * last = image.constScanLine(y - 1);
            //const uchar * line = image.constScanLine(y);
            const uchar * next = image.constScanLine(y + 1);
            uchar * out = ret.scanLine(y);
            for(int x = 1; x < width - 1; x ++)
            {
                int z = abs(last[x - 1] - next[x - 1]
                        + 2 * (last[x] - next[x])
                        + last[x + 1] - next[x + 1]);
                out[x] = qBound(0, z, 255);
            }
        }
    }
    else
    {
        for(int y = 1; y < height - 1; y ++)
        {
            const uchar * last = image.constScanLine(y - 1);
            const uchar * line = image.constScanLine(y);
            const uchar * next = image.constScanLine(y + 1);
            uchar * out = ret.scanLine(y);
            for(int x = 1; x < width - 1; x ++)
            {
                int mx = abs(last[x - 1] - last[x + 1]
                        + 2 * (line[x - 1] - line[x + 1])
                        + next[x - 1] - next[x + 1]);
                int my = abs(last[x - 1] - next[x - 1]
                        + 2 * (last[x] - next[x])
                        + last[x + 1] - next[x + 1]);
                out[x] = qBound(0, qMax(mx, my), 255);
            }
        }
    }
    return ret;
}

EdgeDetector::~EdgeDetector()
{

}

